package cn.enzo.utils.utils;

import java.lang.reflect.Field;
import java.text.MessageFormat;

import org.apache.commons.lang.StringUtils;

import cn.enzo.utils.ann.TableField;

public class SqlMapper implements GenerateMapperSql {

	private final static String Overrides = ",";
	private final static String pre_trim = "<trim prefix=\"(\" suffix=\")\" suffixOverrides=\"" + Overrides + "\">";
	private final static String update_pre_trim = "<trim prefix=\"SET\" suffix=\"WHERE {0}\" suffixOverrides=\"" + Overrides + "\">";
	private final static String suffix_trim = "</trim>";

	private final static String paramvo = "voBean";

	public <T> String getsaveMapper(Class<T> t, String tableName) throws InstantiationException, IllegalAccessException {
		return getSaveMapper(t, tableName, paramvo);
	}

	@Override
	public <T> String getSaveMapper(Class<T> t, String tableName, String param) {
		Field[] fields = t.getDeclaredFields();
		StringBuffer prop = new StringBuffer();
		StringBuffer cloum = new StringBuffer();
		StringBuffer all = new StringBuffer();

		int index = 0;
		param = param == null ? "" : param + ".";
		for (Field field : fields) {
			++index;
			TableField annotation = field.getAnnotation(TableField.class);

			if (null == annotation) {
				continue;
			}
			if (annotation.forkey()) {
				continue;
			}

			if (null != annotation) {
				String value = field.getName();
				String column = StringUtils.isNotEmpty(annotation.column()) ? annotation.column() : field.getName();

				String ifstring = "<if test=\"{2}{0} != null\">" + "{1}" + Overrides + "</if>";
				String format = MessageFormat.format(ifstring, String.format("%-5s", value), String.format("%s", column.toUpperCase()), param);
				prop.append("\t\t").append(format).append("\n");

				String co = "<if test=\"{1}{0} != null\">#'{'{1}{0}}" + Overrides + "</if>";
				String format2 = MessageFormat.format(co, String.format("%s", value), param);
				cloum.append("\t\t").append(format2).append("\n");
			}
			if (index % 5 == 0) {
				prop.append("\n");
				cloum.append("\n");
			}
		}

		all.append("<!-- --------- insert ---------------- -->\n");
		all.append("<insert id=\"save\">\n");
		all.append("\t");
		all.append("INSERT INTO " + tableName.toUpperCase() + "").append("\n");
		all.append("\t").append(pre_trim).append("\n").append(prop).append("\t").append(suffix_trim).append("\n").append("\t").append("VALUES").append("\n").append("\t").append(pre_trim).append("\n").append(cloum).append("\t").append(suffix_trim).append("\n");
		all.append("</insert>");
		return all.toString();
	}

	/**
	 * 
	 * @Description 根据实体得到插入的Mapper文件
	 * @param t
	 *            T
	 * @param tableName
	 *            表名
	 * @param param
	 *            {@link org.apache.ibatis.annotations.Param} 的值
	 * @return insert Mapper
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 *             String
	 */

	public <T> String getUpdateMapper(Class<T> t, String tableName) {
		return getUpdateMapper(t, tableName, paramvo);
	}


	@Override
	public <T> String getUpdateMapper(Class<T> t, String tableName, String param) {
		Field[] fields = t.getDeclaredFields();
		int index = 0;
		StringBuffer prop = new StringBuffer();
		StringBuffer all = new StringBuffer();
		String wherestring = "";
		param = param == null ? "" : param + ".";
		for (Field field : fields) {
			++index;
			TableField annotation = field.getAnnotation(TableField.class);

			if (null == annotation || annotation.forkey())
				continue;

			String value = field.getName();
			String column = StringUtils.isNotEmpty(annotation.column()) ? annotation.column() : field.getName();
			if (annotation.id()) {
				if (wherestring == "") {
					wherestring += column + " = #{" + param + value + "}";
				} else {
					wherestring += " AND " + column + " = #{" + param + value + "}";
				}
			}
			String ifstring = "<if test=\"{2}{0} != null\">" + "{1} = #'{'{2}{0}}" + Overrides + "</if>";
			String format = MessageFormat.format(ifstring, String.format("%-5s", value), String.format("%s", column.toUpperCase()), param);
			prop.append("\t").append(format).append("\n");

			if (index % 5 == 0) {
				prop.append("\n");
			}
		}
		all.append("<!-- ------------- update ---------------- -->\n");
		all.append("<update id=\"update\">\n");
		all.append("UPDATE " + tableName.toUpperCase()).append("\n");
		all.append(MessageFormat.format(update_pre_trim, wherestring)).append("\n");
		all.append(prop);
		all.append(suffix_trim);

		all.append("\n</update>");
		return all.toString();
	}

	public <T> String getDeleteMapper(Class<T> t, String tableName) {
		return getDeleteMapper(t, tableName, paramvo);
	}


	@Override
	public <T> String getDeleteMapper(Class<T> t, String tableName, String param) {
		Field[] fields = t.getDeclaredFields();
		int index = 0;
		StringBuffer prop = new StringBuffer();
		StringBuffer all = new StringBuffer();
		String wherestring = "";
		param = param == null ? "" : param + ".";
		for (Field field : fields) {
			++index;
			TableField annotation = field.getAnnotation(TableField.class);
			if (null == annotation)
				continue;

			String column = StringUtils.isNotEmpty(annotation.column()) ? annotation.column() : field.getName();

			if (annotation.id())
				wherestring += " AND " + column + " = #{key}";

			if (index % 5 == 0)
				prop.append("\n");
		}

		all.append("<!-- --------- delete ---------------- -->\n");
		all.append("<delete id=\"deleteBykey\">\n");
		all.append("DELETE FROM  " + tableName.toUpperCase()).append("\n").append("WHERE 1=1 ").append(wherestring);
		all.append("\n</delete>");
		return all.toString();
	}

	@Override
	public <T> String getJSPTableHtml(Class<T> beanCls) {
		final String vo = "voBean";
		final String td = "td";

		StringBuffer stringBuffer = new StringBuffer();
		StringBuffer stringBuffer2 = new StringBuffer();
		StringBuffer name = new StringBuffer();
		Field[] declaredFields = beanCls.getDeclaredFields();
		for (Field field : declaredFields) {
			TableField annotation = field.getAnnotation(TableField.class);
			stringBuffer2.append("\n\t\t");
			name.append("\t<th>").append(annotation.desc()).append("</th>\n");
			if (field.getType().getName().equals("java.util.Date")) {
				stringBuffer2.append(WrapElement("<fmt:formatDate value=\"${" + vo + "." + field.getName() + "}\" pattern=\"yyyy-MM-dd HH:mm:ss\"/></td>", td));
			} else if (field.getType().getName().equals("java.math.BigDecimal")) {
				stringBuffer2.append(WrapElement("<fmt:formatNumber value=\"${" + vo + "." + field.getName() + "}\" pattern=\"#,##0.00#\"/>", td));
			} else if (field.getType().getName().equals("java.lang.Boolean")) {
				stringBuffer2.append(WrapElement("${" + vo + "." + field.getName() + " ? 'truevalue' : 'falsevalue' }", td));
			} else {
				stringBuffer2.append(WrapElement("${" + vo + "." + field.getName() + "}", td));
			}
		}

		stringBuffer.append(WrapElement(name.toString(), "tr"));

		stringBuffer.append("\n<c:forEach items=\"${pagehelper.list }\" var=\"" + vo + "\">");
		stringBuffer.append("\n\t");
		stringBuffer.append(WrapElement(stringBuffer2.toString(), "tr"));
		stringBuffer.append("\n\t");
		stringBuffer.append("\n</c:forEach>");
		System.out.println(stringBuffer);
		return stringBuffer.toString();
	}


	/**
	 * 
	 * WrapElement("abc","ll") --> <ll>abc</ll>
	 * 
	 * @param value
	 *            abc
	 * @param emelment
	 *            td
	 * @return String
	 */
	private static String WrapElement(String value, String emelment) {

		StringBuffer stringBuffer = new StringBuffer();
		
		stringBuffer.append("<").append(emelment).append(">");
		stringBuffer.append(value);
		stringBuffer.append("</").append(emelment).append(">");

		return stringBuffer.toString();
	}
}
